Skip to content

[iOS] Fix buttons crash when unmounting children#4065

Merged
m-bert merged 3 commits into
mainfrom
@mbert/fix-buttons-unmount-crash
Apr 9, 2026
Merged

[iOS] Fix buttons crash when unmounting children#4065
m-bert merged 3 commits into
mainfrom
@mbert/fix-buttons-unmount-crash

Conversation

@m-bert

@m-bert m-bert commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator

Description

buttonView is UIControl, which unlike RCTViewComponentView does strict checks for view index when unmounting children.

Fixes #4062

Test plan

Tested on example from #4062
import { useState } from 'react';
import { Pressable, Text, View } from 'react-native';
import {
  Clickable,
  GestureHandlerRootView,
} from 'react-native-gesture-handler';

export default function App() {
  const [children, setChildren] = useState<React.ReactNode[]>([]);

  return (
    <GestureHandlerRootView
      style={[
        { flex: 1, alignItems: 'center', justifyContent: 'center' },
        { marginTop: 25 },
      ]}>
      <Clickable>
        <Text>Clickable</Text>

        {children.map((child, index) => (
          <View key={index}>{child}</View>
        ))}
      </Clickable>

      <Pressable
        onPress={() =>
          setChildren([
            ...children,
            <Text key={children.length}>New child</Text>,
          ])
        }>
        <Text>Add child to Clickable</Text>
      </Pressable>

      <Pressable onPress={() => setChildren(children.slice(0, -1))}>
        <Text>Remove child from Clickable</Text>
      </Pressable>
    </GestureHandlerRootView>
  );
}

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an iOS (Fabric) crash when removing children from the Gesture Handler Clickable/button component by changing how child views are unmounted from the underlying UIControl.

Changes:

  • Update RNGestureHandlerButtonComponentView unmount behavior to avoid UIControl’s strict index checks during child unmount.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- (void)unmountChildComponentView:(RNGHUIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[_buttonView unmountChildComponentView:childComponentView index:index];
[childComponentView removeFromSuperview];

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unmountChildComponentView:index: now calls removeFromSuperview on the child without verifying it’s still mounted under _buttonView. Since removeFromSuperview detaches from whatever the current superview is, this can unmount the view from a different parent if it has already been reattached elsewhere. Consider guarding on childComponentView.superview == _buttonView (or deriving the current index from _buttonView.subviews and using that), and explicitly mark index as unused to avoid unused-parameter warnings.

Suggested change
[childComponentView removeFromSuperview];
(void)index;
if (childComponentView.superview == _buttonView) {
[childComponentView removeFromSuperview];
}

Copilot uses AI. Check for mistakes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@m-bert m-bert merged commit ae91e3a into main Apr 9, 2026
3 checks passed
@m-bert m-bert deleted the @mbert/fix-buttons-unmount-crash branch April 9, 2026 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Clickable][iOS] Crash after removing children

3 participants